﻿import random
from games.XO.Rules.XOrules import *

def _flipTurn(who):
	if who == Xchar:
		return Ochar
	return Xchar

def getRandomTurn(turns):
	return turns[random.choice(range(len(turns)))]

#рекурсивный перебор всех вариантов ходов с принципом минимакса
#задается 
#	- текущее поле
#	- минимальная длина цепочки для победы
#	- уровень AI (определяет глубину рекурсивного погружения), если 0 - полный обход
#	- чей ход
#	- за кого "болеем"
#в случае равенства нескольких вариантов выбирается случайный
def makeBestTurn(fld, minChain, aiLevel, whoseTurn, whoI):
	global cnt
	turns = getAllTurns(fld)
	if len(turns) == 0:
		raise Exception("It's mistake")
	
	if aiLevel > 0:
		aiLevel -= 1
		if aiLevel <=0:
			return (0, getRandomTurn(turns)) 
	
	if (whoI == whoseTurn):
		resMiniMax = -99999
	else:
		resMiniMax = +99999
	
	for turn in turns:
		newFld = list(fld)
		makeTurn(newFld, whoseTurn, turn)
		whoseWin_ = whoseWin(newFld, minChain)
		if whoseWin_ == Xchar or whoseWin_ == Ochar:
			if whoseWin_ == whoI:
				return (1, turn)
			else:
				return (-1, turn)
		elif whoseWin_ == NBchar:
			return (0, turn)
		
		(best, bestTurn) = makeBestTurn(newFld, minChain, aiLevel, _flipTurn(whoseTurn), whoI)
		if (whoI == whoseTurn):
			if (best > resMiniMax):
				resMiniMax = best
				resMiniMaxTurn = [turn]
			elif best == resMiniMax:
				resMiniMaxTurn.append(turn)
		elif (whoI != whoseTurn):
			if (best < resMiniMax):
				resMiniMax = best
				resMiniMaxTurn = [turn]
			elif best == resMiniMax:
				resMiniMaxTurn.append(turn)
	return (resMiniMax, getRandomTurn(resMiniMaxTurn))

def getAllTurns(fld):
	l = getLfield(fld)
	return [(x, y) for x in range(l) for y in range(l) if fld[y*l + x] == Fchar]